home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 May / macformat-024.iso / Shareware City / Developers / TransSkel Pascal 2.5 / TransSkel / MultiSkel ƒ / MSkelRgn.p < prev    next >
Encoding:
Text File  |  1994-12-12  |  5.2 KB  |  218 lines  |  [TEXT/PJMM]

  1. {    TransSkel multiple-window demonstration: Region module}
  2.  
  3. {    This module handles a window in which the mouse may be clicked and}
  4. {    dragged to draw rectangles.  The rects so drawn are combined into}
  5. {    a single region, the outline of which is drawn.  Rects drawn while}
  6. {    the shift key is held down are subtracted from the region.}
  7. {    Double-clicking the mouse clears the display.  If the window is}
  8. {    resized, the region that is drawn is resized as well.}
  9.  
  10. {    14 June 1986        Paul DuBois}
  11.  
  12. {    Changes:}
  13. {    07/08/86 Changed outline so that it's drawn as a marquee.}
  14. {    Ported to LightSpeed Pascal 7 January 1987                    }
  15. {    By Owen Hartnett, Ωhm Software                                }
  16. {    30 December 1987 OH changed to support version 1.03 }
  17.  
  18. unit MSkelRgn;
  19. interface
  20.  
  21.     uses
  22. {$IFC UNDEFINED THINK_PASCAL}
  23.         Memtypes, Quickdraw, OSIntf, ToolIntf, PackIntf, 
  24. {$ENDC}
  25.         transSkel, multiSkelGlobals, common;
  26.  
  27.     procedure RgnWindInit;
  28.  
  29.  
  30. implementation
  31.  
  32.     var
  33.         rgnPortRect: Rect;    { portRect size - for detecting wind grows }
  34.         selectRgn: RgnHandle;        { current region to be drawn }
  35.         selectWhen: longint;        { time of last click }
  36.         selectWhere: Point;    { location of last click }
  37.         marqueePat: Pattern;
  38.  
  39.     procedure Clobber;
  40.  
  41.     begin
  42.         DisposeRgn(selectRgn);
  43.         CloseWindow(rgnWind);
  44.     end;
  45.  
  46. {    While mouse is down, draw gray selection rectangle in the current}
  47. {    port.  Return the resultant rect in dstRect.  The rect is always}
  48. {    clipped to the current portRect.}
  49.  
  50.  
  51.     procedure DoSelectRect (startPoint: point; var dstRect: Rect);
  52.  
  53.         var
  54.             pt, dragPt: Point;
  55.             rClip: Rect;
  56.             thePort: GrafPtr;
  57.             result: Boolean;
  58.             ps: PenState;
  59.             i: integer;
  60.  
  61.     begin
  62.         GetPort(thePort);
  63.         rClip := thePort^.portRect;
  64.         rClip.right := rClip.right - 15;
  65.         GetPenState(ps);
  66. {$IFC UNDEFINED THINK_PASCAL}
  67.         PenPat(qd.gray);
  68. {$ELSEC}
  69.         PenPat(gray);
  70. {$ENDC}
  71.         PenMode(patXor);
  72.         dragPt := startPoint;
  73.         Pt2Rect(dragPt, dragPt, dstRect);
  74.         FrameRect(dstRect);
  75.         while StillDown do
  76.             begin
  77.                 GetMouse(pt);
  78.                 if not EqualPt(pt, dragPt) then    { mouse has moved, change region }
  79.                     begin
  80.                         FrameRect(dstRect);
  81.                         dragPt := pt;
  82.                         Pt2Rect(dragPt, startPoint, dstRect);
  83.                         result := SectRect(dstRect, rClip, dstRect);
  84.                         FrameRect(dstRect);
  85.                         for i := 0 to 1000 do
  86.                             ;
  87.                     end;
  88.             end;
  89.         FrameRect(dstRect);    { erase last rect }
  90.         SetPenState(ps);
  91.     end;
  92.  
  93.     procedure MarqueeRgn (r: RgnHandle);
  94.  
  95.         var
  96.             p: PenState;
  97.             b: Byte;
  98.             i: integer;
  99.  
  100.     begin
  101.         GetPenState(p);
  102.         PenPat(marqueePat);
  103.         PenMode(patCopy);
  104.         FrameRgn(r);
  105.         SetPenState(p);
  106.         b := marqueePat[0];        { shift pattern for next call }
  107.         for i := 0 to 6 do
  108.             marqueePat[i] := marqueePat[i + 1];
  109.         marqueePat[7] := b;
  110.     end;
  111.  
  112.     procedure Idle;
  113.  
  114.         var
  115.             i: integer;
  116.  
  117.     begin
  118.         SetWindClip(rgnWind);
  119.         MarqueeRgn(selectRgn);    { draw selection region outline }
  120.         ResetWindClip;            { restore previous clipping }
  121.     end;
  122.  
  123. {    On double-click, clear window.  On single click, draw gray selection}
  124. {    rectangle as long as mouse is held down.  If user draws non-empty rect,}
  125. {    then add it to the selection region and redraw the region's outline.}
  126. {    If the shift-key was down, then subtract the selection region instead}
  127. {    and redraw.}
  128.  
  129.  
  130.     procedure Mouse (thePt: Point; t: longint; mods: integer);
  131.  
  132.         var
  133.             r: Rect;
  134.             rgn: RgnHandle;
  135.  
  136.     begin
  137.         r := rgnWind^.portRect;
  138.         if thePt.h < r.right - 15 then        { must not click in right edge }
  139.             begin
  140.                 if (t - selectWhen <= GetDblTime) then    { it's a double-click }
  141.                     begin
  142.                         selectWhen := 0;        { don't take next click as dbl-click }
  143.                         SetWindClip(rgnWind);
  144.                         EraseRgn(selectRgn);
  145.                         ResetWindClip;
  146.                         SetEmptyRgn(selectRgn);    { clear region }
  147.                     end
  148.                 else
  149.                     begin
  150.                         selectWhen := t;                { update click variables }
  151.                         selectWhere := thePt;
  152.                         DoSelectRect(thePt, r);    { draw selection rectangle }
  153.                         if not EmptyRect(r) then
  154.                             begin
  155.                                 EraseRgn(selectRgn);
  156.                                 selectWhen := 0;
  157.                                 rgn := NewRgn;
  158.                                 RectRgn(rgn, r);
  159.                                 if (Bitand(mods, shiftKey)) <> 0 then        { test shift key }
  160.                                     DiffRgn(selectRgn, rgn, selectRgn)
  161.                                 else
  162.                                     unionRgn(selectRgn, rgn, selectRgn);
  163.                                 DisposeRgn(rgn);
  164.                             end;
  165.                     end;
  166.             end;
  167.     end;
  168.  
  169. {    Redraw the current region.  If the window was resized, resize}
  170. {    the region to fit.}
  171.  
  172.     procedure Update (resized: Boolean);
  173.  
  174.         var
  175.             r: Rect;
  176.  
  177.     begin
  178.         EraseRect(rgnWind^.portRect);
  179.         if resized then
  180.             begin
  181.                 r := rgnWind^.portRect;
  182.                 rgnPortRect.right := rgnPortrect.right - 15;    { don't use right edge of window }
  183.                 r.right := r.right - 15;
  184.                 MapRgn(selectRgn, rgnPortRect, r);
  185.                 rgnPortRect := rgnWind^.portRect
  186.             end;
  187.         DrawGrowBox(rgnWind);
  188.         idle;
  189.     end;
  190.  
  191.     procedure Activate (active: Boolean);
  192.  
  193.     begin
  194.         DrawGrowBox(rgnWind);
  195.         if active then
  196.             DisableItem(editMenu, 0)
  197.         else
  198.             EnableItem(editMenu, 0);
  199.         DrawMenuBar;
  200.     end;
  201.  
  202.     procedure RgnWindInit;
  203.  
  204.     begin
  205.         StuffHex(@marqueePat, '0f87c3e1f0783c1e');
  206.         rgnWind := GetNewWindow(rgnWindRes, nil, WindowPtr(-1));
  207.         dummy := SkelWindow(rgnWind, @Mouse, nil, @update, @activate, nil, @Clobber, @Idle, true);
  208.         { ignore keyclicks }
  209.         { no close proc }
  210.     { disposal proc }
  211.         { idle proc }
  212.  
  213.         rgnPortRect := rgnWind^.portRect;
  214.         selectRgn := NewRgn;    { selected region empty initially }
  215.  
  216.         selectWhen := 0;    { first click can't be taken as dbl-click }
  217.     end;
  218. end.